package com.example.myapplication.ui.upload

import android.annotation.SuppressLint
import android.app.Activity
import android.content.Intent
import android.graphics.Color
import android.os.Build
import android.view.View
import android.widget.ImageView
import android.widget.TextView
import androidx.core.view.children
import androidx.core.view.isVisible
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.example.myapplication.App
import com.example.myapplication.DEFAULT_CHUNK_SIZE
import com.example.myapplication.R
import com.example.myapplication.utils.DiffUIDataUtil
import com.example.myapplication.common.AbstractFragment
import com.example.myapplication.extensions.beGone
import com.example.myapplication.extensions.beVisible
import com.example.myapplication.extensions.runOnUIThread
import com.example.myapplication.extensions.toast
import com.example.myapplication.ui.FileBean.Companion.STATE_DEFAULT_FLAG
import com.example.myapplication.ui.FileBean.Companion.STATE_LOCAL_FLAG
import com.example.myapplication.ui.FileBean.Companion.STATE_NET_FLAG
import com.example.myapplication.ui.upload.FileUploadBean.Companion.UPLOAD_ERROR
import com.example.myapplication.ui.upload.FileUploadBean.Companion.UPLOAD_FINISH
import com.example.myapplication.ui.upload.FileUploadBean.Companion.UPLOAD_READY
import com.example.myapplication.ui.upload.FileUploadBean.Companion.UPLOAD_RUNNING
import com.example.myapplication.utils.OpenUtil
import com.example.myapplication.utils.UriUtils
import com.example.myapplication.view.SideSlipLayout
import com.example.myapplication.view.SimpleRecyclerAdapter
import java.io.File
import kotlin.Exception

class FileUploadFragment : AbstractFragment() {

    companion object {
        const val OPEN_FILE_MANAGER_REQUEST_CODE = 2048
    }

    private val viewModel: FileUploadViewModel by lazy {
        ViewModelProvider(
            requireActivity()
        ).get(FileUploadViewModel::class.java)
    }

    override fun getContentLayoutId(): Int {
        return R.layout.fragment_file_upload
    }

    private val adapter = object : SimpleRecyclerAdapter<FileUploadBean>() {
        override fun getItemViewType(position: Int, data: FileUploadBean): Int {
            if (data.type == 0) {
                return R.layout.item_title_file
            }
            return R.layout.item_upload_file
        }

        override fun onCreateViewHolder(
            contentView: View,
            viewType: Int
        ): SimpleViewHolder<FileUploadBean> {
            if (viewType == R.layout.item_title_file) {
                return TitleViewHolder(contentView)
            }
            return ViewHolder(contentView)
        }

        override fun updateView(view: View) {
            super.updateView(view)
            val parent = view.parent
            if (parent is RecyclerView) {
                parent.children.forEach {
                    if (it != view && it is SideSlipLayout) {
                        it.setOpenByAnimation(false)
                    }
                }
            }
        }
    }
    /**
     * 初始化控件
     */
    override fun initView(contentView: View) {
        super.initView(contentView)
        contentView.findViewById<RecyclerView>(R.id.rv_file_upload).also {
            it.itemAnimator = null
            it.adapter = adapter
            it.layoutManager = LinearLayoutManager(contentView.context)
            it.addOnChildAttachStateChangeListener(adapter.childStateChangeListener)
        }
    }
    /**
     * 首次初始化
     */
    override fun onFirstInit() {
        super.onFirstInit()
        viewModel.updateAllTaskState()
    }
    /**
     * 初始化数据
     */
    override fun initData() {
        super.initData()
        this.lifecycle.addObserver(viewModel)
        viewModel.getAllFileByFlow().observe(this, { words ->
            requireContext().runOnUIThread {
                val old = adapter.getItems()
                val callback = DiffUIDataUtil(old, words)
                val result = DiffUtil.calculateDiff(callback)
                adapter.getItems().clear()
                adapter.getItems().addAll(words)
                result.dispatchUpdatesTo(adapter)
            }
        })
    }
    /**
     * 普通Viewholder
     */
    inner class ViewHolder(itemView: View) :
        SimpleRecyclerAdapter.SimpleViewHolder<FileUploadBean>(itemView) {

        private val name: TextView
        private val uploadState: TextView
        private val speed: TextView
        private val retry: View
        private val icon: ImageView

        init {
            name = itemView.findViewById(R.id.name)
            uploadState = itemView.findViewById(R.id.state)
            speed = itemView.findViewById(R.id.speed)
            itemView.findViewById<View>(R.id.retry).also {
                this.retry = it
            }.setOnClickListener { retryBean() }
            icon = itemView.findViewById(R.id.icon)
            itemView.findViewById<View>(R.id.tv_delete).setOnClickListener {
                deleteBean()
            }
            itemView.findViewById<View>(R.id.tag_sild_slip_layout_left_view).setOnClickListener {
                // 打开文件
                openBean()
            }
            itemView.findViewById<SideSlipLayout>(R.id.side_silp_layout).sildListener =
                object : SideSlipLayout.SideSlipListener {
                    override fun onMenuState(isShow: Boolean, contentView: View) {
                        if (isShow) {
                            callback?.updateView(itemView)
                        }
                    }
                }
        }

        @SuppressLint("SetTextI18n")
        override fun onBindView(newData: FileUploadBean, oldData: FileUploadBean?) {
            equalToUpdataUI(newData.path, oldData?.path) {
                try {
                    val path = newData.path ?: throw Exception("path is null")
                    val file = File(path)
                    if (!file.exists()) throw Exception("file is not exists")
                    val type = file.extension
                    when (type.lowercase()) {
                        "pdf" -> icon.setBackgroundResource(R.mipmap.pdf_icon)
                        "jpg", "png" -> icon.setBackgroundResource(R.mipmap.image_icon)
                        "doc", "docx" -> icon.setBackgroundResource(R.mipmap.word_icon)
                        "xls", "xlsx" -> icon.setBackgroundResource(R.mipmap.excel_icon)
                        "vsd", "vsdx" -> icon.setBackgroundResource(R.mipmap.v_icon)
                        "ppt", "pptx" -> icon.setBackgroundResource(R.mipmap.ppt_icon)
                        else -> icon.setBackgroundResource(R.mipmap.not_supper_icon)
                    }
                } catch (e: Exception) {
                    icon.setBackgroundResource(R.mipmap.image_nfind_icon)
                }
            }

            equalToUpdataUI(newData.name, oldData?.name) {
                name.text = it
            }

            equalToUpdataUI(newData.state, oldData?.state) {
                val value: String
                if (it.startsWith(STATE_NET_FLAG)) {
                    uploadState.setTextColor(Color.RED)
                    value = it.substringAfter(STATE_NET_FLAG)
                } else if (it.startsWith(STATE_LOCAL_FLAG)) {
                    uploadState.setTextColor(Color.RED)
                    value = it.substringAfter(STATE_LOCAL_FLAG)
                } else {
                    uploadState.setTextColor(Color.BLACK)
                    value = it.substringAfter(STATE_DEFAULT_FLAG)
                }
                uploadState.text = value
            }

            equalToUpdataUI(newData.uploadSpeed, oldData?.uploadSpeed) {
                speed.text = "${it}KB/S"
            }

            if (newData.uploadState != UPLOAD_ERROR) {
                retry.beGone()
            } else {
                retry.beVisible()
            }

            if (retry.isVisible) {
                speed.beGone()
            } else {
                if (newData.uploadState == UPLOAD_READY || newData.uploadState == UPLOAD_FINISH) {
                    speed.beGone()
                } else {
                    speed.beVisible()
                }
            }
        }

        private fun deleteBean() {
            mData?.also {
                if (itemView is SideSlipLayout) {
                    itemView.setOpen(false)
                }
                viewModel.delete(it)
            }
        }

        private fun retryBean() {
            mData?.also {
                viewModel.retry(it)
            }
        }

        private fun openBean() {
            try {
                val path = mData?.path ?: throw Exception("path is null")
                val intent = OpenUtil.openFileByIntent(requireActivity(), path)
                    ?: throw Exception("Intent is null")
                requireActivity().startActivity(intent)
            } catch (e: Exception) {
                requireActivity().toast("打开失败，请重试")
            }
        }
    }
    /**
     * 分割Viewholder
     */
    inner class TitleViewHolder(itemView: View) :
        SimpleRecyclerAdapter.SimpleViewHolder<FileUploadBean>(itemView) {

        private val name: TextView
        private val active: TextView

        init {
            name = itemView.findViewById(R.id.title)
            active = itemView.findViewById(R.id.active)
        }

        override fun onBindView(newData: FileUploadBean, oldData: FileUploadBean?) {
            equalToUpdataUI(newData.name, oldData?.name) {
                name.text = it
            }
            equalToUpdataUI(newData.uploadState, oldData?.uploadState) {
                if (it == UPLOAD_FINISH) {
                    active.setText("全部删除")
                    active.setOnClickListener {
                        viewModel.deleteAll()
                    }
                }
            }
        }
    }
    /**
     * 文件获取回调
     */
    @SuppressLint("ObsoleteSdkInt")
    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        if (isVisible && resultCode == Activity.RESULT_OK && requestCode == OPEN_FILE_MANAGER_REQUEST_CODE) {
            val uri = data?.data//得到uri，后面就是将uri转化成file的过程。
            val path: String
            if (Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT) {//4.4以后
                path = UriUtils.getPath(this.requireContext(), uri)
            } else {//4.4以下下系统调用方法
                path = UriUtils.getRealPathFromURI(this.requireContext(), uri)
            }
            val file = File(path)
            if (file.exists()) {
                if (file.extension.equals("exe", true)) {
                    context?.toast("文件格式[${file.extension}]不支持")
                    return
                }
                viewModel.insert(FileUploadBean().apply {
                    this.name = file.name
                    this.length = file.length()
                    this.path = path
                    this.state = "${STATE_DEFAULT_FLAG}正在等待..."
                    this.chunkNumber =
                        Math.ceil(this.length.toDouble() / DEFAULT_CHUNK_SIZE).toInt()
                })
            }
        }
        super.onActivityResult(requestCode, resultCode, data)
    }

    override fun onMoreItemSelected(value: String): Boolean {
        when (value) {
            "打开" -> {
                openFileManager()
            }
            "预设" -> {
                createTile()
            }
            "清空进行" -> {
                viewModel.deleteRunningTask()
            }
            "刷新失败" -> {
                viewModel.updateErrorTask()
            }
            "清空失败" -> {
                viewModel.deleteErrorTask()
            }
        }
        return super.onMoreItemSelected(value)
    }

    private fun openFileManager() {
        val intent = Intent(Intent.ACTION_GET_CONTENT);
        intent.setType("*/*");//设置类型，我这里是任意类型，任意后缀的可以这样写。
        intent.addCategory(Intent.CATEGORY_OPENABLE);
        startActivityForResult(intent, OPEN_FILE_MANAGER_REQUEST_CODE);
    }

    private fun createTile() {
        viewModel.insert(FileUploadBean().apply {
            this.name = "进行中"
            this.uploadState = UPLOAD_RUNNING
            this.type = 0
            this.enabled = false
        })
        viewModel.insert(FileUploadBean().apply {
            this.name = "已完成"
            this.uploadState = UPLOAD_FINISH
            this.type = 0
            this.enabled = false
        })
    }

}